#!/usr/bin/env python

import pygame, sys, math, random
import Numeric

from accel import AccelControl

from vector import *

MAXRADIUS=35.0

current=None

def aacircle(radius = 10, antialias = 2, color = [0,255, 128], width = 0):
	' Paint a circle'
	BLACK = (0, 0, 0)
	WHITE = (255, 255, 255)
	d = radius * 2
	r2 = radius * antialias
	d2 = r2 * 2


	# Create surface twice the size (or more)
	pic = pygame.Surface([d2, d2], 0, 8)
	pic.set_palette([[x, x, x] for x in range(256)])
	pic.fill(BLACK)


	# Draw the circle on the large picture
	pygame.draw.circle(pic, WHITE, [r2, r2], r2, width)


	# Add the pixel values to a temporary array
	array = Numeric.zeros((d, d), Numeric.Int)
	srcarray = pygame.surfarray.pixels2d(pic)
	for x in range(d2):
		for y in range(d2):
			array[x/antialias][y/antialias] += srcarray[x][y]
	array /= antialias * antialias


	# Create the final surface
	pic2 = pygame.Surface([d, d], pygame.SRCALPHA, 32).convert_alpha()
	pic2.fill(color)
	pygame.surfarray.pixels_alpha(pic2)[:, :] = array.astype(Numeric.UInt8)
	
	# Return the final surface
	return pic2


class Pop(pygame.sprite.Sprite):

	def __init__(self, pos=None):
		pygame.sprite.Sprite.__init__(self)
		popsound.play()
		self.pos=pos
		self.image=popimg
		self.age=100
		self.update()

	def update(self):
		self.age-=1
		if self.age<0:
			self.kill()
		self.rect=pygame.Rect(self.pos[0]-16, self.pos[1]-16, 32,32)
	

class Circle(pygame.sprite.Sprite):

	def __init__(self, pos=None):
		pygame.sprite.Sprite.__init__(self)
		if pos==None:
			self.y=random.randint(10,470)
			self.x=random.randint(0, 630)
		else:
			self.x, self.y=pos
		self.radius=1
		self.c=(255,255,255)
		self.growing=True
		self.age=random.randint(3000,5000)

	def update(self,*args):
		if self.growing:
			self.radius+=3
			self.x, self.y=pygame.mouse.get_pos()
			self.x+=random.randint(-3,3)/10.0
			self.y+=random.randint(-3,3)/10.0
			if self.radius>=MAXRADIUS:
				self.growing=False
				self.radius=MAXRADIUS
		else:
			if args:
				self.x+=args[0][0]*(self.radius/MAXRADIUS)
				self.y+=args[0][1]*(self.radius/MAXRADIUS)

			self.y+=random.randint(-3,3)/10.0
			self.x+=random.randint(-3,3)/10.0

		self.age-=1
		if self.age<0:
			self.kill()

		if self.x+self.radius<0: self.kill()
		if self.x-self.radius>480: self.kill()
		if self.y-self.radius>640: self.kill()
		if self.y+self.radius<0: self.kill()

		self.image=circleimg[int(self.radius)-1]
		self.rect=pygame.Rect(self.x-self.radius, self.y-self.radius, self.radius*2, self.radius*2)

	def kill(self):
		pops.add(Pop(self.pos()))
		pygame.sprite.Sprite.kill(self)
		

	def pos(self):
		return self.x, self.y



def input(events):
	global current
	
	for event in events:
		if event.type == pygame.QUIT: 
			sys.exit(0)
		elif event.type == pygame.KEYDOWN:
			# scancode 177 = aux
			if event.key == pygame.K_ESCAPE or event.scancode==177:
				sys.exit(0)
		elif event.type == pygame.MOUSEBUTTONDOWN:
			current=Circle(pygame.mouse.get_pos())
			bubbles.add(current)
		elif event.type == pygame.MOUSEBUTTONUP:
			if current!=None:
				current.growing=False
	   

def load_sound(name):
	class NoneSound:
		def play(self): pass
	if not pygame.mixer:
		return NoneSound()
	try:
		sound = pygame.mixer.Sound(name)
	except pygame.error, message:
		print "Cannot load sound:", name
		raise SystemExit, message
	return sound


if __name__=="__main__":
	pygame.init()

	if not pygame.mixer: print 'Warning, sound disabled'

	#window = pygame.display.set_mode((480, 640))
	window = pygame.display.set_mode((480, 640), pygame.FULLSCREEN|pygame.HWSURFACE|pygame.OPENGL)
	
	screen = pygame.display.get_surface() 

	# load sound
	popsound=load_sound("data/pop.wav")
	# creates graphics

	sys.stdout.write("Creating graphics: ")

	popimg=pygame.Surface((32,32))
	lines=7
	for i in range(0, lines):
		sx=16+5*math.cos(i*(2*math.pi/lines))
		sy=16+5*math.sin(i*(2*math.pi/lines))
		ex=16+12*math.cos(i*(2*math.pi/lines))
		ey=16+12*math.sin(i*(2*math.pi/lines))
		pygame.draw.line(popimg, (255,255,255), (sx,sy), (ex,ey))
		sys.stdout.write(".")
		sys.stdout.flush()

	circleimg=[]
	for i in range(0, MAXRADIUS):
		circleimg.append(aacircle(i+1, width=min(i+1,3), color=(0,156,255)))
		sys.stdout.write(".")
		sys.stdout.flush()

	print "Done."

	a=AccelControl()

	# the accelerometer position when we start.
	origin=a.read()
	ox,oy,oz=origin

	print circleimg[0].get_flags(), circleimg[0].get_bitsize()

	bubbles=pygame.sprite.Group()
	pops=pygame.sprite.Group()

	if pygame.font:
		font = pygame.font.Font(None, 16)
		
	points=0

	print "Bubbles!"
	while True: 
		input(pygame.event.get())

		# input: 
 		acx,acy,acz=a.read()

 		ax=(ox-acx)/100.0
 		ay=(oy-acy)/100.0
		
		# x is inversed
		ax*=-1
		

 		# collisions
 		for b in bubbles:
 			for c in bubbles:
 				if c==b: continue
 				d=dist(b.pos(), c.pos())
 				offset=(b.radius+c.radius)-d
 				if offset>0:
 					v=normal((b.x-c.x, b.y-c.y))
 					v=scale(v,offset/2)
 					b.x+=v[0]
 					b.y+=v[1]
 					c.x-=v[0]
 					c.y-=v[1]
					

		# draw it all
		bubbles.update((ax,ay))
		pops.update()

		# blank
		screen.fill((0,0,0))

		pops.draw(screen)
		bubbles.draw(screen)

		# score
# 		if pygame.font:
# 			text = font.render("%d"%points, 1, (255,255,255))
# 			screen.blit(text,(0,0))

		pygame.display.flip()

		# dump debug things

		sys.stdout.write("\r% 5.2f, % 5.2f"%(ax,ay))

		sys.stdout.flush()


